﻿Ext.util.Functions = {

    //创建一个拦截器函数。origFn为原函数，它被新函数拦截
    //newFn为新函数，它拦截原函数，即先运行newFn，如果newFn的返回值不为false，才运行origFn（两个函数的参数是一样的）
    //scope是新函数newFn的作用域，returnValue是新函数newFn返回为false时拦截器函数的返回值
    //总结：createInterceptor返回一个函数，该函数的返回值在origFn运行时是origFn运行的返回值，
    //在origFn被拦截时返回的是returnValue
    createInterceptor: function (origFn, newFn, scope, returnValue) {
        var method = origFn;
        if (!Ext.isFunction(newFn)) {//如果newFn不是函数，则返回原函数
            return origFn;
        }
        else {
            return function () {
                var me = this,
                    args = arguments;
                newFn.target = me;
                newFn.method = origFn;
                return (newFn.apply(scope || me || window, args) !== false) ?
                        origFn.apply(me || window, args) :
                        returnValue || null;
            };
        }
    },

    //创建一个委托函数（就是回调）。
    //fn是原函数，运行委托函数的过程中就运行了原函数
    //obj是原函数的作用域
    //args是附加参数
    //appendArgs是附加参数的追加形式，未定义或为false则覆盖本次调用委托函数的参数列表，
    //为true表示在末尾追加，为数字表示在下标处插入
    createDelegate: function (fn, obj, args, appendArgs) {

        if (!Ext.isFunction(fn)) {//如果fn不是函数，直接返回fn
            return fn;
        }
        return function () {//否则返回一个委派对象

            var callArgs = args || arguments; 

            if (appendArgs === true) {//追加参数args
                callArgs = Array.prototype.slice.call(arguments, 0);//返回函数的参数数组
                callArgs = callArgs.concat(args); //将createDelegate的参数args加到返回函数的参数数组后面
            }
            else if (Ext.isNumber(appendArgs)) {//把参数args插到指定位置
                callArgs = Array.prototype.slice.call(arguments, 0);

                var applyArgs = [appendArgs, 0].concat(args);//[appendArgs, 0, args]

                //callArgs.splice(appendArgs, 0, args),从appendArgs位置开始删除元素，删除0个元素，插入args
                Array.prototype.splice.apply(callArgs, applyArgs);

            }
            return fn.apply(obj || window, callArgs);//运行fn函数，返回fn的运行结果
        };
    },

    //延迟调用该函数
    //fn是原函数
    //millis是延迟时间
    //obj是原函数的作用域
    //args是附加给委托函数的参数
    //appendArgs是附加参数的追加方式
    defer: function (fn, millis, obj, args, appendArgs) {
        fn = Ext.util.Functions.createDelegate(fn, obj, args, appendArgs);//创建委托函数
        if (millis > 0) {
            return setTimeout(fn, millis);//延迟millis毫秒调用fn
        }
        fn();//没有延迟则直接调用
        return 0;
    },


    //创建一个组合函数，调用次序为：origFn + newFn。该函数返回了origFn执行的结果。
    createSequence: function (origFn, newFn, scope) {

        if (!Ext.isFunction(newFn)) {//如果newFn不是函数，直接返回origFn
            return origFn;
        }
        else {//否则返回一个组合函数
            return function () {
                var retval = origFn.apply(this || window, arguments);//执行原函数
                newFn.apply(scope || this || window, arguments);//执行新函数
                return retval;
            };
        }
    }
};



Ext.defer = Ext.util.Functions.defer;



Ext.createInterceptor = Ext.util.Functions.createInterceptor;



Ext.createSequence = Ext.util.Functions.createSequence;


Ext.createDelegate = Ext.util.Functions.createDelegate;